home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / video / fly8111-.000 / fly8111- / fly8 / hud.c < prev    next >
C/C++ Source or Header  |  1979-12-31  |  12KB  |  582 lines

  1. /* --------------------------------- hud.c ---------------------------------- */
  2.  
  3. /* This is part of the flight simulator 'fly8'.
  4.  * Author: Eyal Lebedinsky (eyal@ise.canberra.edu.au).
  5. */
  6.  
  7. /* paint the Head Up Display.
  8. */
  9.  
  10. #include "plane.h"
  11.  
  12.  
  13. #define DOGRAPH        (st.debug & DF_GPX)
  14.  
  15. extern void FAR
  16. show_hud (VIEW *view, OBJECT *pov, OBJECT *p, int orgx, int orgy,
  17.     int maxx, int maxy, int mode)
  18. {
  19.     int    hud, hud1, hud2, big, htype, hudarea, limit, front, hon;
  20.     int    sx, sy, tx, ty, ttx, tty;
  21.     int    x, y, ss, clipx, clipy, shifty;
  22.     ANGLE    a;
  23.     HUD    h[1];
  24.  
  25. /* hud only for planes, in front view
  26. */
  27.     if (!IS_PLANE(CV) || (HDT_HUD != mode && !scenery (mode))) {
  28.         alarm_set (0);
  29.         return;
  30.     }
  31.  
  32.     hud = EX->hud;
  33.     hud1 = EX->hud1;
  34.     hud2 = EX->hud2;
  35.     big = hud & HUD_BIG;
  36.     htype = hud1 & HUD_TYPES;
  37.     front = !view->viewport->rotz && !view->viewport->rotx;
  38.     x = HDT_FRONT == mode && (hud & HUD_ON) && front;
  39.     hon = x || HDT_HUD == mode;
  40.     limit = (x && (hud1 & HUD_LIMIT)) || HDT_HUD == mode;
  41.  
  42.     get_square (view, maxx, maxy, &sx, &sy);
  43.  
  44.     if (0 == (tx = (sx+32)/64))
  45.         tx = 1;
  46.     if (0 == (ty = (sy+32)/64))
  47.         ty = 1;
  48.  
  49.     shifty = EX->hudshift;
  50.     if (HDT_HUD == mode) {
  51.         orgy -= fmul (sy, shifty);
  52.     } else {
  53.         y = sy + fmul (sy, shifty);
  54.         if ((maxy>>1) >= y)
  55.             hudarea = FCON(1.99);
  56.         else
  57.             hudarea = fdiv (maxy, y);    /* largest allowed */
  58.         a = DEG2ANG (EX->hudarea);
  59.         y = muldiv (VP->z, SIN (a), COS (a));
  60.         if (y < VP->maxy) {            /* fits in window */
  61.             y = muldiv (y, maxy, VP->maxy);    /* y pixels */
  62.             y = fdiv (y, sy);        /* ratio */
  63.             if (y < hudarea)        /* fits in square */
  64.                 hudarea = y;
  65.         }
  66.         sx = fmul (sx, hudarea);
  67.         sy = fmul (sy, hudarea);
  68.         if (sx > maxx) {
  69.             sy = muldiv (sy, maxx, sx);
  70.             sx = maxx;
  71.         }
  72.         if (sy > maxy) {
  73.             sx = muldiv (sx, maxy, sy);
  74.             sy = maxy;
  75.         }
  76.     }
  77.  
  78.     ss = fmul (sy, EX->hudFontSize);
  79.     if (ss < 8)
  80.         ss = 8;
  81.  
  82.     if (!big && HUD_CLASSIC == htype) {
  83.         x = 3*tx;
  84.         y = 2+tx + num_size (99L, ss);
  85.         if (y > x)
  86.             x = y;
  87.         if (maxx-x < sx) {
  88.             x = maxx-x;
  89.             sy = muldiv (sy, x, sx);
  90.             sx = x;
  91.         }
  92.  
  93.         y = 2+3*ty+ss;
  94.         if (maxy-y < sy) {
  95.             y = maxy-y;
  96.             sx = muldiv (sx, y, sy);
  97.             sy = y;
  98.         }
  99.     }
  100.     if (0 == (tx = (sx+32)/64))
  101.         tx = 1;
  102.     if (0 == (ty = (sy+32)/64))
  103.         ty = 1;
  104.  
  105.     shifty = fmul (sy, shifty);
  106.  
  107.     if (limit) {
  108.         clipx = sx;
  109.         clipy = sy;
  110.     } else {
  111.         clipx = maxx;
  112.         clipy = maxy;
  113.     }
  114.  
  115.     h->flags = 0;
  116.  
  117.     h->orgx = orgx;        /* window sizes */
  118.     h->orgy = orgy;
  119.     h->maxx = maxx;
  120.     h->maxy = maxy;
  121.  
  122.     h->shifty = shifty;        /* hud sizes */
  123.     h->cx = orgx;
  124.     h->cy = orgy+shifty;
  125.     h->sx = sx;
  126.     h->sy = sy;
  127.  
  128.     h->clipx =  clipx;        /* clip sizes */
  129.     h->clipy =  clipy;
  130.     h->clipr =  clipx;        /* clip rectangle, relative */
  131.     h->clipl = -clipx;
  132.     h->clipt =  clipy - shifty;
  133.     h->clipb = -clipy - shifty;
  134.  
  135.     h->right  = orgx + h->clipr;    /* hud border, absolute */
  136.     h->left   = orgx + h->clipl;
  137.     h->top    = orgy - h->clipt;
  138.     h->bottom = orgy - h->clipb;
  139.  
  140.     h->tx = h->ttx = tx;
  141.     h->ty = h->tty = ty;
  142.     h->ss = ss;
  143.     h->dd = num_size (9L, ss);
  144.     h->width = 0;
  145.     h->height = 0;
  146.     h->fg = ST_HFG;
  147.     h->fgi = ST_HFGI;
  148.     h->VV[X] = h->VV[Y] = 0;
  149.  
  150.     if (WIN_ETHER == st.windows && HUD_ETHER == (EX->hud1 & HUD_TYPES)) {
  151.             h->flags |= HF_ETHER;
  152.         if (st.flags & SF_MAIN)
  153.                 h->flags |= HF_ETHERFRAME;
  154.     }
  155.  
  156.     if (h->flags & HF_ETHERFRAME) {
  157.         get_area (&st.hdd[4].view, 0, 0, &x, &y);
  158.         h->etherx  = (h->maxx + x) / 2 + 1;
  159.         h->ethery  = (h->maxy + y) / 2 + 1;
  160.         x = h->etherx - h->maxx - 2;
  161.         y = h->ethery - h->maxy - 2;
  162.         get_square (&st.hdd[4].view, x*8, y*8, &x, &y);
  163.         h->ethertx = x/8;
  164.         h->etherty = y/8;
  165.     }
  166.  
  167.     hud_alarm (h, p, ST_HFGI, mode, hon);
  168.  
  169.     if (hon) {
  170.         if (big) {
  171.             h->ttx = -h->ttx;
  172.             h->tty = -h->tty;
  173.         }
  174.         ttx = h->ttx;
  175.         tty = h->tty;
  176. /* hud border
  177. */
  178.         if ((hud1 & HUD_BORDER) && HDT_FRONT == mode)
  179.             show_rect (h->cx, h->cy, h->sx, h->sy, ST_HBO, 0);
  180.  
  181. /* velocity vector
  182. */
  183.         show_vv (h, view, p, ST_HFG);
  184.  
  185. /* waterline mark.
  186. */
  187.         show_wl (h, p, ST_HFG);
  188.  
  189. /* pitch ladder is centered on the vv or the waterline mark
  190. */
  191.         show_pitch (h, view, p, sx, sy, maxx, maxy, orgx, orgy,
  192.             ttx, tty, tx, ty, ss, shifty, mode, h->VV);
  193.  
  194. /* heading on upper/lower edge
  195. */
  196.         show_heading (h, view, p, sx, sy, maxx, maxy, orgx, orgy,
  197.             ttx, tty, tx, ty, ss, shifty, h->VV);
  198.  
  199. /* waypoint (experimental).
  200. */
  201.         show_waypoint (h, view, p);
  202.  
  203. /* altitude on right edge
  204. */
  205.         show_altitude (h, p, sx, sy, maxx, maxy, orgx, orgy, ttx, tty,
  206.             tx, ty, ss, shifty, h->VV);
  207. /* speed on left edge
  208. */
  209.         show_speed (h, p, sx, sy, maxx, maxy, orgx, orgy,
  210.             ttx, tty, tx, ty, ss, shifty, h->VV);
  211. /* ILS
  212. */
  213.         show_ils (h, p, sx, sy, orgx, orgy, ss, shifty);
  214.  
  215. /* Bullets trail history.
  216. */
  217.         show_trail (h, view, p);
  218.     }
  219.  
  220. /* Show radar stuff
  221. */
  222.     if (HDT_HUD == mode || scenery (mode))
  223.         show_radar (h, view, p, pov, orgx, orgy, maxx, maxy, tx, ty,
  224.             ss, clipx, clipy, sx, sy, limit ? shifty : 0, h->VV,
  225.             mode, hon);
  226.  
  227. /* ailerons/elevators cursor (helps keypad/mouse mode)
  228. */
  229.     if ((hud & HUD_CURSOR) && p->pointer) {
  230.         x = orgx + muldiv (-p->pointer->a[0], sx-tx, 100);
  231.         y = orgy + muldiv (-p->pointer->a[1], sy-ty, 100) + shifty;
  232.  
  233.         show_rect (x, y, tx, ty, ST_CFG, 0);
  234.     }
  235.  
  236. /* cross hair
  237. */
  238.     if ((hud & HUD_PLUS) || (HDT_MAP == mode || HDT_RADAR == mode))
  239.         show_bplus (h->orgx, h->orgy, h->tx*3, h->ty*3, FCON(0.125),
  240.             ST_HFG);
  241.  
  242. /* debug: show Cm/alpha graph.
  243. */
  244.     if (DOGRAPH) {
  245.         show_plus (h->cx, h->cy, h->sx, h->sy, ST_CFG);
  246.         x = fmul (EX->aoa, sx*3);
  247.         if (x > sx)
  248.             x = sx;
  249.         else if (x < -sx)
  250.             x = -sx;
  251.         y = EX->misc[5];
  252.         if (y > 10000)
  253.             y = 10000;
  254.         else if (y < -10000)
  255.             y = -10000;
  256.         y = muldiv (y , sy-ty, 10000);
  257.         x = h->cx + x;
  258.         y = h->cy - y;
  259.         show_rect (x, y, tx, ty, ST_CFG, 0);    /* show point */
  260.     }
  261. }
  262.  
  263. extern void FAR
  264. show_num (int x, int y, long t, int s, int c, int orgx, int orgy, int maxx,
  265.     int maxy, int shifty)
  266. {
  267.     int    dxs, dxc, dys, dyc, l, h;
  268.  
  269.     num_extent (t, s, &dxs, &dxc, &dys, &dyc);
  270.  
  271.     --maxx;            /* fight truncation errors */
  272.     --maxy;
  273.  
  274.     l = orgx-maxx-x;
  275.     h = orgx+maxx-x;
  276.     if (0 > h || 0 < l)
  277.         return;
  278.     if (dxc > h || dxc < l)
  279.         return;
  280.     if (-dys > h || -dys < l)
  281.         return;
  282.     if (dxc-dys > h || dxc-dys < l)
  283.         return;
  284.  
  285.     l = orgy+shifty-maxy-y;
  286.     h = orgy+shifty+maxy-y;
  287.     if (0 > h || 0 < l)
  288.         return;
  289.     if (-dxs > h || -dxs < l)
  290.         return;
  291.     if (-dyc > h || -dyc < l)
  292.         return;
  293.     if (-dxs-dyc > h || -dxs-dyc < l)
  294.         return;
  295.  
  296.     stroke_num (x, y, t, s, c);
  297. }
  298.  
  299. extern void FAR
  300. add_segment (int x1, int y1, int x2, int y2, int orgx, int orgy,
  301.     int sx, int sy, int shifty)
  302. {
  303.     int    i, z1, z2, xl, xh, yl, yh;
  304.  
  305. /* Not quite midpoint clipping, if both ends are out then we reject the
  306.  * segment which is mostly ok.
  307. */
  308.     xh = orgx+sx;
  309.     xl = orgx-sx;
  310.     yh = orgy+sy+shifty;
  311.     yl = orgy-sy+shifty;
  312.  
  313.     z1 = x1>xh || x1<xl || y1>yh || y1<yl;
  314.     z2 = x2>xh || x2<xl || y2>yh || y2<yl;
  315.  
  316.     if (z1) {
  317.         if (z2)
  318.             return;
  319.         i = x1; x1 = x2; x2 = i;
  320.         i = y1; y1 = y2; y2 = i;
  321.     } else if (!z2) {
  322.         gr_line (x1, y1, x2, y2);
  323.         return;
  324.     }
  325.  
  326.     gr_move (x1, y1);
  327.  
  328.     i = iabs(x2-x1);
  329.     z1 = iabs(y2-y1);
  330.     if (i < z1)
  331.         i = z1;
  332.     for (; i > 1; i >>= 1) {
  333.         z1 = (x1 + x2)/2;
  334.         z2 = (y1 + y2)/2;
  335.         if (z1>xh || z1<xl || z2>yh || z2<yl) {
  336.             x2 = z1;
  337.             y2 = z2;
  338.         } else {
  339.             x1 = z1;
  340.             y1 = z2;
  341.         }
  342.     }
  343.  
  344.     gr_draw (x1, y1);
  345. }
  346.  
  347. extern void FAR
  348. add_dash (int x1, int y1, int x2, int y2, int ndash, int ratio,
  349.     int orgx, int orgy, int sx, int sy)
  350. {
  351.     register int    dx, dy;
  352.     int        i, rx, ry, xl, xh, yl, yh;
  353.  
  354.     if (!ndash)
  355.         return;
  356.  
  357.     xl = orgx - sx;
  358.     xh = orgx + sx;
  359.     yl = orgy - sy;
  360.     yh = orgy + sy;
  361.  
  362.     ratio /= ndash;
  363.     x2 -= x1;
  364.     y2 -= y1;
  365.  
  366. /* Do symmetric truncation.
  367. */
  368.     if (x2 < 0)
  369.         rx = -fmul (-x2, ratio);
  370.     else
  371.         rx = fmul (x2, ratio);
  372.     if (y2 < 0)
  373.         ry = -fmul (-y2, ratio);
  374.     else
  375.         ry = fmul (y2, ratio);
  376.  
  377.     for (i = 0; i < ndash; ++i) {
  378.         dx = x1 + muldiv (x2, i, ndash);
  379.         dy = y1 + muldiv (y2, i, ndash);
  380.         if (dx < xl || dx > xh || dy < yl || dy > yh)
  381.             continue;
  382.         gr_move (dx, dy);
  383.         dx += rx;
  384.         dy += ry;
  385.         if (dx < xl || dx > xh || dy < yl || dy > yh)
  386.             continue;
  387.         gr_draw (dx, dy);
  388.     }
  389. }
  390.  
  391. extern void FAR
  392. screen_coords (VIEW *view, VECT RR)
  393. {
  394.     int    s;
  395.  
  396.     s = VP->z;                /* get minimum */
  397.     if (s > VP->maxx)
  398.         s = VP->maxx;
  399.     if (s > VP->maxy)
  400.         s = VP->maxy;
  401.     RR[X] = muldiv (RR[X], s, VP->maxx);
  402.     RR[Z] = muldiv (RR[Z], s, VP->maxy);
  403.     RR[Y] = muldiv (RR[Y], s, VP->z);
  404. }
  405.  
  406. /* clip the point in R into the screen point D. Note that is the point is
  407.  * inside the screen then a simple projection is done. Otherwise, a point
  408.  * on the edge is returned. If the depth is negative then still clip to
  409.  * the edge.
  410. */
  411. extern int FAR
  412. clip_to_screen (int D[2], VECT R, int maxx, int maxy, int clipx, int clipy,
  413.     int shifty)
  414. {
  415.     int    off_screen, clip, x, y, ry, t;
  416.  
  417.     off_screen = 0;            /* some classic clipping */
  418.  
  419.     if (R[Y] <= 0) {
  420.         ry = -R[Y];
  421.         clip = 0;
  422.     } else
  423.         clip = ry = R[Y];
  424.  
  425. /* Establish position relative to the clipping pyramid for the screen.
  426. */
  427.     if (R[X] >= clip)
  428.         off_screen |= 1;    /* right */
  429.     else if (-R[X] >= clip)
  430.         off_screen |= 2;    /* left */
  431.  
  432.     if (R[Z] >= clip)
  433.         off_screen |= 4;    /* top */
  434.     else if (-R[Z] >= clip)
  435.         off_screen |= 8;    /* bottom */
  436.  
  437. /* Resolve the corner areas into the correct clipping edge.
  438. */
  439.     if (off_screen == 5)        /* top right */
  440.         if (R[X] > R[Z])
  441.             off_screen = 1;
  442.         else
  443.             off_screen = 4;
  444.     else if (off_screen == 9)    /* bottom right */
  445.         if (R[X] > -R[Z])
  446.             off_screen = 1;
  447.         else
  448.             off_screen = 8;
  449.     else if (off_screen == 6)    /* top left */
  450.         if (-R[X] > R[Z])
  451.             off_screen = 2;
  452.         else
  453.             off_screen = 4;
  454.     else if (off_screen == 10)    /* bottom left */
  455.         if (-R[X] > -R[Z])
  456.             off_screen = 2;
  457.         else
  458.             off_screen = 8;
  459.     else
  460.         {}
  461.  
  462. /* Now do the projection and clipping together.
  463. */
  464.     switch (off_screen) {
  465.     default:
  466.     case 0:
  467.         if (ry == 0)
  468.             x = y = 0;
  469.         else {
  470.             x = muldiv (maxx, R[X], ry);
  471.             y = muldiv (maxy, R[Z], ry);
  472.         }
  473.         break;
  474.     case 1:                        /* right */
  475.         x = maxx;
  476.         if (R[X] == 0)
  477.             y = 0;
  478.         else
  479.             y = muldiv (maxy, R[Z], R[X]);
  480.         break;
  481.     case 2:                        /* left */
  482.         x = -maxx;
  483.         if (R[X] == 0)
  484.             y = 0;
  485.         else
  486.             y = -muldiv (maxy, R[Z], R[X]);
  487.         break;
  488.     case 4:                        /* top */
  489.         if (R[Z] == 0)
  490.             x = 0;
  491.         else
  492.             x = muldiv (maxx, R[X], R[Z]);
  493.         y = maxy;
  494.         break;
  495.     case 8:                        /* bottom */
  496.         if (R[Z] == 0)
  497.             x = 0;
  498.         else
  499.             x = -muldiv (maxx, R[X], R[Z]);
  500.         y = -maxy;
  501.         break;
  502.     }
  503.     if (off_screen)
  504.         off_screen = clip ? 1 : 2;
  505.  
  506. /* Finally check for 2D clipping (for the window) and do it.
  507. */
  508.     if (x >= clipx) {
  509.         y = muldiv (clipx, y, x);
  510.         x = clipx;
  511.         if (!off_screen)
  512.             off_screen = 1;
  513.     } else if (x <= -clipx) {
  514.         y = -muldiv (clipx, y, x);
  515.         x = -clipx;
  516.         if (!off_screen)
  517.             off_screen = 1;
  518.     }
  519.     if (y >= (t = clipy-shifty)) {
  520.         x = muldiv (t, x, y);
  521.         y = t;
  522.         if (!off_screen)
  523.             off_screen = 1;
  524.     } else if (y <= (t = -clipy-shifty)) {
  525.         x = muldiv (t, x, y);
  526.         y = t;
  527.         if (!off_screen)
  528.             off_screen = 1;
  529.     }
  530.  
  531.     D[X] = x;
  532.     D[Y] = y;
  533.     return (off_screen);
  534. }
  535.  
  536. extern void FAR
  537. clip_to_ether (HUD *h, int D[2], int x, int y)
  538. {
  539.     if (D[X] >= x)
  540.         D[X] = h->etherx;
  541.     else if (D[X] <= -x)
  542.         D[X] = -h->etherx;
  543.     if (D[Y] >= y)
  544.         D[Y] = h->ethery;
  545.     else if (D[Y] <= -y)
  546.         D[Y] = -h->ethery;
  547. }
  548.  
  549. extern int FAR
  550. keep_inside (int *x, int *y, int xl, int xh, int yl, int yh, int orgx,
  551.     int orgy, int clipx, int clipy, int shifty)
  552. {
  553.     int    t;
  554.     int    ret = 0;
  555.  
  556.     if (xl > xh)
  557.         (t = xl, xl = xh, xh = t);
  558.     if (*x > (t = orgx+clipx-xh))
  559.         *x = t, ret = 1;
  560.     else if (*x < (t = orgx-clipx-xl))
  561.         *x = t, ret = 1;
  562.  
  563.     if (yl > yh)
  564.         (t = yl, yl = yh, yh = t);
  565.     orgy += shifty;
  566.     if (*y > (t = orgy+clipy-yh))
  567.         *y = t, ret = 1;
  568.     else if (*y < (t = orgy-clipy-yl))
  569.         *y = t, ret = 1;
  570.  
  571.     return (ret);
  572. }
  573.  
  574. extern int FAR
  575. is_in (HUD *h, int x, int y, int dx, int dy)
  576. {
  577.     return (x < h->right-dx && x > h->left+dx &&
  578.         y > h->top+dy   && y < h->bottom-dy);
  579. }
  580.  
  581. #undef DOGRAPH
  582.